package com.ruoyi.web.api.controller.system;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.AppUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.domain.model.WxMiniAppLoginBody;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.Polygon;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.security.manager.WxMiniAppManager;
import com.ruoyi.framework.web.service.AppLoginService;
import com.ruoyi.system.domain.Area;
import com.ruoyi.system.domain.SysWxUser;
import com.ruoyi.system.service.IAppUserService;
import com.ruoyi.system.service.IAreaService;
import com.ruoyi.system.service.ISysWxUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import static com.ruoyi.common.core.domain.AjaxResult.success;

/**
 * App用户登录验证
 *
 * @author ruoyi
 */
@Api(tags = "小程序端用户登录")
@RestController
public class AppLoginController {
    private final AppLoginService loginService;

    private final ISysWxUserService wxUserService;

    private final IAppUserService appUserService;

    private final IAreaService areaService;

    @Resource
    private WxMiniAppManager wxMiniAppManager;

    public AppLoginController(AppLoginService loginService, ISysWxUserService wxUserService, IAppUserService appUserService, IAreaService areaService) {
        this.loginService = loginService;
        this.wxUserService = wxUserService;
        this.appUserService = appUserService;
        this.areaService = areaService;
    }

    /**
     * 登录方法
     *
     * @param loginBody 登录信息
     * @return 结果
     */
    @PostMapping("/login")
    @ApiOperation(value = "账号密码登录", notes = "获取用户信息")
    public AjaxResult login(@RequestBody LoginBody loginBody) {
        AjaxResult ajax = success();
        // 生成令牌
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), Constants.LOGIN_TYPE_PASSWORD, loginBody.getUuid(), loginBody.getCode());
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }

    @PostMapping("/wxLogin")
    @ApiOperation(value = "微信小程序登陆", notes = "微信小程序登陆")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult wxMaLogin(@Valid @RequestBody WxMiniAppLoginBody wxMiniAppLoginDTO) {
        // 获取微信小程序session信息
        JSONObject sessionObj = wxMiniAppManager.getSessionInfo(wxMiniAppLoginDTO.getCode());
        String openid = sessionObj.getString("openid");
        String unionid = sessionObj.getString("unionid");

        // 查询微信用户是否存在
        SysWxUser wxUser = wxUserService.selectSysWxUserByOpenId(openid);
        AppUser user;
        Date now = new Date();

        if (wxUser == null) {
            // 微信用户不存在，创建用户和微信用户
            // 1.创建普通用户
            user = new AppUser();
            user.setUserType(Constants.APP_USER_CUSTOM);
            user.setCreateTime(now);
            user.setUserRegtime(now);
            user.setStatus(1);

            // 获取当前时间并格式化为 "20250710104301" 格式
            String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
            if (wxMiniAppLoginDTO.getMobile() == null) {
                user.setLoginName("微信用户" + timestamp);
            } else {
                user.setLoginName("微信用户" + timestamp);
            }
            appUserService.insertAppUser(user);

            // 2.创建微信用户并关联
            wxUser = new SysWxUser();
            wxUser.setWxUserId(UUID.randomUUID().toString().replace("-", ""));
            wxUser.setUserId(user.getId());
            wxUser.setOpenId(openid);
            wxUser.setUnionId(unionid);
            wxUser.setNickName(user.getLoginName());
            wxUser.setCreateTime(now);
            wxUser.setUpdateTime(now);
            wxUserService.insertSysWxUser(wxUser);
        } else {
            // 微信用户存在，更新用户信息
            user = appUserService.selectAppUserById(wxUser.getUserId());
            if (user == null) {
                throw new ServiceException("用户不存在");
            }
        }

        String token = loginService.login(user.getLoginName(), null, Constants.LOGIN_TYPE_WX, null, null);
        AjaxResult ajax = success();
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }

    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @GetMapping("/getInfo")
    @ApiOperation(value = "获取用户信息", notes = "获取用户信息")
    public AjaxResult getInfo() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        AppUser user = appUserService.selectAppUserById(loginUser.getUserId());
        user.setLoginPassword(null);
        AjaxResult ajax = success();
        ajax.put("user", user);
        return ajax;
    }

    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @GetMapping("/getArea")
    @ApiOperation(value = "获取用户当前区域", notes = "获取用户当前区域")
    public AjaxResult getCurrentArea(@ApiParam("经度") double lng,
                                     @ApiParam("纬度") double lat) {

        List<Area> areas = areaService.selectAreaList(new Area());
        for (Area area : areas) {
            double[][] polygons = Polygon.buildPath(area.getCoordinates());
            Polygon polygon = new Polygon(polygons);
            boolean in = polygon.contains(lng, lat);

            if (in) {
                LoginUser loginUser = SecurityUtils.getLoginUser();
                AppUser user = loginUser.getAppUser();
                user.setLoginPassword(null);
                AjaxResult ajax = success();
                ajax.put("area", area);
                return ajax;
            }
        }
        AjaxResult ajax = success();
        ajax.put("area", null);
        return ajax;
    }

    /**
     * 修改用户
     */
    @ApiOperation(value = "修改用户", notes = "修改用户信息")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody AppUser appUser) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        AppUser user = loginUser.getAppUser();
        appUser.setId(user.getId());
        return success(appUserService.updateAppUser(appUser));
    }
}